﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Printing;
using NGridDrawer.Partitions;
using NGridDrawer.Report;
using NGridDrawer.Report.Layout;

namespace NGridDrawer.Components
{
    ///<summary>
    /// This class Provide a basic way to attach a comment with a cell in a grid of data 
    ///</summary>
    [ToolboxBitmap(typeof (PrintDocument), "PrintDocument.bmp")]
    public class GridAnnotatedDrawerComponent : DrawerComponent
    {
        /// <summary>
        /// 	<para>Initializes an instance of the <see cref="GridAnnotatedDrawerComponent"/> class.</para>
        /// </summary>
        public GridAnnotatedDrawerComponent()
        {
            initializeInternal();
        }

        /// <summary>
        /// 	<para>Initializes an instance of the <see cref="GridAnnotatedDrawerComponent"/> class.</para>
        /// </summary>
        /// <param name="container"></param>
        public GridAnnotatedDrawerComponent(IContainer container)
            : base(container)
        {
            initializeInternal();
        }

        /// <summary>
        /// Occurs when rows are under process
        /// </summary>
        /// <remarks>
        /// Raise this event if you want to attach an <see cref="IBlock"/> instance to a row
        /// </remarks>
        public event EventHandler<RowRequestedBlockEventArgs> RowRequestedBlock;



        private GridAnnotatedDrawer encapsulatedDrawer { get; set; }

        /// <summary>Get Drawer property</summary>
        [Browsable(false)]
        public override IPartitionDrawer Drawer
        {
            get { return encapsulatedDrawer; }
        }


        private void initializeInternal()
        {
            PropertyChanged += onPropertyChanged;
        }




        void onPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (Equals(sender) && e.PropertyName.Equals("Component")
                || sender.Equals(Component) && e.PropertyName.Equals("Drawer"))
            {
                // update drawer
                if (Component == null || Component.Drawer == null)
                {
                    if (encapsulatedDrawer != null)
                    {
                        encapsulatedDrawer.RowRequestedBlock -= encapsulatedDrawer_RowRequestedBlock;
                        encapsulatedDrawer = null;
                        OnPropertyChanged("Drawer");
                    }
                }
                else
                {
                    if (encapsulatedDrawer == null)
                    {
                        encapsulatedDrawer = CreateEncapsulatedDrawer();
                        encapsulatedDrawer.RowRequestedBlock += encapsulatedDrawer_RowRequestedBlock;
                        OnPropertyChanged("Drawer");
                    }
                    else if (!encapsulatedDrawer.DecoratedDrawer.Equals(Component.Drawer))
                    {
                        encapsulatedDrawer.DecoratedDrawer = Component.Drawer;
                        OnPropertyChanged("Drawer");
                    }
                }
            }
        }





        private void encapsulatedDrawer_RowRequestedBlock(object sender, RowRequestedBlockEventArgs e)
        {
            if (RowRequestedBlock != null)
                RowRequestedBlock(sender, e);
        }


        ///<summary>
        /// Load a <see cref="GridAnnotatedDrawer"/> instance
        ///</summary>
        ///<returns>Return the loaded instance</returns>
        protected virtual GridAnnotatedDrawer CreateEncapsulatedDrawer()
        {
            return new GridAnnotatedDrawer(Component.Drawer);
        }
    }
}